/* NOTICE
 
    Jim - the Java Image Manager, copyright (c) 2005 - 2007 Grant Gardner 
 
    Jim is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Jim is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
    In addition, as a special exception, you are permitted to link this code
    with the 3rd party libraries required to compile this file and to
    distribute a linked combination including them. You must obey the
    GNU General Public License in all respects for all of the code except for
    those 3rd party libraries that are licenced under terms incompatible with the
    GNU General Public License.  
 
 
 NOTICE */

/*
 * Created by dnoakes on 27-Nov-2002 10:12:05 using IntelliJ IDEA.
 */

package au.com.lastweekend.jim.io.exif.makernote.fujifilm;

import au.com.lastweekend.jim.io.metadata.Directory;
import au.com.lastweekend.jim.io.metadata.MetadataException;
import au.com.lastweekend.jim.io.metadata.AbstractTagDescriptor;
import au.com.lastweekend.jim.util.Rational;

/**
 * Fujifilm's digicam added the MakerNote tag from the Year2000's model (e.g.Finepix1400, Finepix4700). It uses IFD format and
 * start from ASCII character 'FUJIFILM', and next 4 bytes(value 0x000c) points the offset to first IFD entry. Example of actual
 * data structure is shown below.
 * 
 * :0000: 46 55 4A 49 46 49 4C 4D-0C 00 00 00 0F 00 00 00 :0000: FUJIFILM........ :0010: 07 00 04 00 00 00 30 31-33 30 00 10 02 00
 * 08 00 :0010: ......0130......
 * 
 * There are two big differences to the other manufacturers. - Fujifilm's Exif data uses Motorola align, but MakerNote ignores it
 * and uses Intel align. - The other manufacturer's MakerNote counts the "offset to data" from the first byte of TIFF header (same
 * as the other IFD), but Fujifilm counts it from the first byte of MakerNote itself.
 * 
 * @version $Id: FujifilmMakernoteDescriptor.java,v 1.2 2005/06/09 11:15:39 ggardner Exp $
 * @author <a href="mailto:grant@lastweekend.com.au"> <Grant Gardner> </a>
 */
public class FujifilmMakernoteDescriptor extends AbstractTagDescriptor {

    public FujifilmMakernoteDescriptor(Directory directory) {

        super(directory);
    }

    @Override
    public String getDescription(int tagType) throws MetadataException {

        switch (tagType) {
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_SHARPNESS :
                return getSharpnessDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_WHITE_BALANCE :
                return getWhiteBalanceDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_COLOR :
                return getColorDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_TONE :
                return getToneDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_FLASH_MODE :
                return getFlashModeDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_FLASH_STRENGTH :
                return getFlashStrengthDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_MACRO :
                return getMacroDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_FOCUS_MODE :
                return getFocusModeDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_SLOW_SYNCHRO :
                return getSlowSyncDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_PICTURE_MODE :
                return getPictureModeDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING :
                return getContinuousTakingOrAutoBrackettingDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_BLUR_WARNING :
                return getBlurWarningDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_FOCUS_WARNING :
                return getFocusWarningDescription();
            case FujiFilmMakernoteDirectory.TAG_FUJIFILM_AE_WARNING :
                return getAutoExposureWarningDescription();
            default :
                return getDirectory().getString(tagType);
        }
    }

    private String getAutoExposureWarningDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_AE_WARNING)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_AE_WARNING);
        switch (value) {
            case 0 :
                return "AE good";
            case 1 :
                return "Over exposed (>1/1000s @ F11)";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getFocusWarningDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FOCUS_WARNING)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FOCUS_WARNING);
        switch (value) {
            case 0 :
                return "Auto focus good";
            case 1 :
                return "Out of focus";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getBlurWarningDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_BLUR_WARNING)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_BLUR_WARNING);
        switch (value) {
            case 0 :
                return "No blur warning";
            case 1 :
                return "Blur warning";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getContinuousTakingOrAutoBrackettingDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING)) {
            return null;
        }

        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING);
        switch (value) {
            case 0 :
                return "Off";
            case 1 :
                return "On";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getPictureModeDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_PICTURE_MODE)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_PICTURE_MODE);
        switch (value) {
            case 0 :
                return "Auto";
            case 1 :
                return "Portrait scene";
            case 2 :
                return "Landscape scene";
            case 4 :
                return "Sports scene";
            case 5 :
                return "Night scene";
            case 6 :
                return "Program AE";
            case 256 :
                return "Aperture priority AE";
            case 512 :
                return "Shutter priority AE";
            case 768 :
                return "Manual exposure";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getSlowSyncDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_SLOW_SYNCHRO)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_SLOW_SYNCHRO);
        switch (value) {
            case 0 :
                return "Off";
            case 1 :
                return "On";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getFocusModeDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FOCUS_MODE)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FOCUS_MODE);
        switch (value) {
            case 0 :
                return "Auto focus";
            case 1 :
                return "Manual focus";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getMacroDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_MACRO)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_MACRO);
        switch (value) {
            case 0 :
                return "Off";
            case 1 :
                return "On";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getFlashStrengthDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FLASH_STRENGTH)) {
            return null;
        }
        Rational value = getDirectory().getRational(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FLASH_STRENGTH);
        return value.toSimpleString(false) + " eV (Apex)";
    }

    private String getFlashModeDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FLASH_MODE)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_FLASH_MODE);
        switch (value) {
            case 0 :
                return "Auto";
            case 1 :
                return "On";
            case 2 :
                return "Off";
            case 3 :
                return "Red-eye reduction";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getToneDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_TONE)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_TONE);
        switch (value) {
            case 0 :
                return "Normal (STD)";
            case 256 :
                return "High (HARD)";
            case 512 :
                return "Low (ORG)";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getColorDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_COLOR)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_COLOR);
        switch (value) {
            case 0 :
                return "Normal (STD)";
            case 256 :
                return "High";
            case 512 :
                return "Low (ORG)";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getWhiteBalanceDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_WHITE_BALANCE)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_WHITE_BALANCE);
        switch (value) {
            case 0 :
                return "Auto";
            case 256 :
                return "Daylight";
            case 512 :
                return "Cloudy";
            case 768 :
                return "DaylightColor-fluorescence";
            case 769 :
                return "DaywhiteColor-fluorescence";
            case 770 :
                return "White-fluorescence";
            case 1024 :
                return "Incandenscense";
            case 3840 :
                return "Custom white balance";
            default :
                return "Unknown (" + value + ")";
        }
    }

    private String getSharpnessDescription() throws MetadataException {

        if (!getDirectory().containsTag(FujiFilmMakernoteDirectory.TAG_FUJIFILM_SHARPNESS)) {
            return null;
        }
        int value = getDirectory().getInt(FujiFilmMakernoteDirectory.TAG_FUJIFILM_SHARPNESS);
        switch (value) {
            case 1 :
            case 2 :
                return "Soft";
            case 3 :
                return "Normal";
            case 4 :
            case 5 :
                return "Hard";
            default :
                return "Unknown (" + value + ")";
        }
    }

    @Override
    public boolean isTagUpdateable(int tagType) {

        return false;
    }
}